﻿

namespace Common.Algorithm.Core;

public class Cube
{
    /// <summary>
    /// 左下角
    /// </summary>
    public Point3d minPnt { get; set; }
    /// <summary>
    /// 前右上角
    /// </summary>
    public Point3d maxPnt { get; set; }


    public Cube(Point3d _pnt1, Point3d _pnt3, bool toCheck = false)
    {
        if (toCheck)
        {
            this.minPnt = new Point3d(Math.Min(_pnt1.X, _pnt3.X), Math.Min(_pnt1.Y, _pnt3.Y), Math.Min(_pnt1.Z, _pnt3.Z));// 
            this.maxPnt = new Point3d(Math.Max(_pnt1.X, _pnt3.X), Math.Max(_pnt1.Y, _pnt3.Y), Math.Max(_pnt1.Z, _pnt3.Z));// 
        }
        else
        {
            this.minPnt = _pnt1;
            this.maxPnt = _pnt3;
        }
    }

    /// <summary>
    /// 判断矩形框是否相交
    /// </summary>
    /// <param name="Extend"></param>
    /// <returns></returns>
    public bool IsIntersect(Cube cube)
    {
        if (
            this.minPnt.X > cube.maxPnt.X || this.minPnt.Y > cube.maxPnt.Y ||
            this.minPnt.X > cube.maxPnt.X || this.minPnt.Y > cube.maxPnt.Y ||
            this.maxPnt.Z < cube.minPnt.Z || this.maxPnt.Z < cube.minPnt.Z
            )
        {
            return false;
        }
        return true;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public Point3d[] GenCornerPnt()
    {
        Point3d[] pnts = new Point3d[8]; 

        pnts[0] = this.topLeftBackPnt;
        pnts[1] = this.topLeftFrntPnt;
        pnts[2] = this.topRigtFrntPnt;
        pnts[3] = this.topRigtBackPnt;

        pnts[4] = this.btmLeftBackPnt;
        pnts[5] = this.btmLeftFrntPnt;
        pnts[6] = this.btmRigtFrntPnt;
        pnts[7] = this.btmRigtBackPnt;

        return pnts;
    }

    public IList<Cube> SplitCube()
    {
        List<Cube> cubes = new List<Cube>(){
             new Cube( topLeftBackPnt    , midMidPnt   ,true  ),
             new Cube( topRigtBackPnt    , midMidPnt   ,true  ),
             new Cube( topLeftFrntPnt    , midMidPnt   ,true  ),
             new Cube( topRigtFrntPnt    , midMidPnt   ,true  ),

             new Cube( btmLeftBackPnt    , midMidPnt   ,true  ),
             new Cube( btmRigtBackPnt    , midMidPnt   ,true  ),
             new Cube( btmLeftFrntPnt    , midMidPnt   ,true  ),
             new Cube( btmRigtFrntPnt    , midMidPnt   ,true  ),
        };
        return cubes;
    }

    /// <summary>
    /// 宽度X
    /// </summary>
    public double width => Math.Abs((maxPnt - minPnt).X);
    /// <summary>
    /// 高度Z
    /// </summary>
    public double height => Math.Abs((maxPnt - minPnt).Z);
    /// <summary>
    /// 高度Z
    /// </summary>
    public double deep => Math.Abs((maxPnt - minPnt).Y);


    /// <summary>
    /// 中心
    /// </summary>
    public Point3d midMidPnt => (minPnt + maxPnt) * 0.5;

    public Point3d midBtmPnt => midMidPnt - new Point3d(0, 0, height * 0.5);
    public Point3d midTopPnt => midMidPnt + new Point3d(0, 0, height * 0.5);
    public Point3d midLeftPnt => midMidPnt - new Point3d(width * 0.5, 0, 0);
    public Point3d midRigtPnt => midMidPnt + new Point3d(width * 0.5, 0, 0);
    public Point3d midFrntPnt => midMidPnt - new Point3d(0, deep * 0.5, 0);
    public Point3d midBackPnt => midMidPnt + new Point3d(0, deep * 0.5, 0);

    public Point3d topLeftBackPnt => midTopPnt + new Point3d(-width * 0.5, deep * 0.5, 0);
    public Point3d topRigtBackPnt => midTopPnt + new Point3d(width * 0.5, deep * 0.5, 0);
    public Point3d topLeftFrntPnt => midTopPnt + new Point3d(-width * 0.5, -deep * 0.5, 0);
    public Point3d topRigtFrntPnt => midTopPnt + new Point3d(width * 0.5, -deep * 0.5, 0);


    public Point3d btmLeftBackPnt => midBtmPnt + new Point3d(-width * 0.5, deep * 0.5, 0);
    public Point3d btmRigtBackPnt => midBtmPnt + new Point3d(width * 0.5, deep * 0.5, 0);
    public Point3d btmLeftFrntPnt => midBtmPnt + new Point3d(-width * 0.5, -deep * 0.5, 0);
    public Point3d btmRigtFrntPnt => midBtmPnt + new Point3d(width * 0.5, -deep * 0.5, 0);
}
